<script setup>
import {ref, onMounted} from "vue";
import emitter from '@/utils/emitter.js'
import {createDiscreteApi} from "naive-ui";
import {useUserStore} from "@/stores/user.js";
import {userGetEnemyAPI} from "@/api/user.js";
import {
  CheckmarkCircleSharp as ReadyIcon
} from "@vicons/ionicons5"


let ws = null
let chessboard = []
const {message} = createDiscreteApi(
    ["message", 'dialog', 'notification', 'loadingBar', 'modal']
)
const START = 60
const OFFSET = 40
const BOARD_ITEM = 15
const canvasRef = ref()
const roomList = ref([])
const roomInfo = ref({
  roomName: "",
  enemy: {},
  messageInfo: []
})
const player = ref({
  color: 0,
  isPlay: false
})
const readyStatus = ref({
  player: false,
  enemy: false
})
const draw = (e) => {
  if (player.value.isPlay === false) {
    message.warning("还不是你的回合！")
    return
  }

  if (e.offsetX >= START && e.offsetX < BOARD_ITEM * OFFSET + START) {
    if (e.offsetY >= START && e.offsetY < BOARD_ITEM * OFFSET + START) {
      let x = e.offsetX - START
      let y = e.offsetY - START
      let xx = Math.floor((x + 20) / 40)
      let yy = Math.floor((y + 20) / 40)
      if (chessboard[xx][yy] !== 0) {
        message.error("此位置被下过啦！！！")
      } else {
        // chessboard[xx][yy] = player.value.color
        chessboard[xx][yy] = player.value.color
        player.value.isPlay = false
        ws.send(JSON.stringify({
          type: "play",
          data: {x: xx, y: yy, color: player.value.color, roomName: roomInfo.value.roomName}
        }))
        if (isWin(xx, yy)) {
          ws.send(JSON.stringify({type: "win", data: roomInfo.value.roomName}))
        }
        drawCanvas()
      }

    }
  }
}
const isWin = (cx, cy) => {
  const p = chessboard[cx][cy]
  for (let x = cx - 4; x <= cx; x++) {
    let cnt = 0
    for (let d = 0; d < 5; d++) {
      if (x < 0 || x + d >= BOARD_ITEM) break
      if (chessboard[x + d][cy] === p) cnt += 1
    }
    if (cnt === 5)
      return true
  }
  for (let y = cy - 4; y <= cy; y++) {
    let cnt = 0
    for (let d = 0; d < 5; d++) {
      if (y < 0 || y + d >= BOARD_ITEM) break
      if (chessboard[cx][y + d] === p) cnt += 1
    }
    if (cnt === 5)
      return true
  }
  let x = cx - 4, y = cy - 4;
  while (x <= cx && y <= cy) {
    let cnt = 0;
    for (let d = 0; d < 5; d++) {
      if (x < 0 || y < 0 || x + d >= BOARD_ITEM || y + d >= BOARD_ITEM) break
      if (chessboard[x + d][y + d] === p) cnt += 1
    }
    if (cnt === 5)
      return true
    x++;
    y++;
  }
  x = cx + 4;
  y = cy - 4;
  while (x >= cx && y <= cy) {
    let cnt = 0
    for (let d = 0; d < 5; d++) {
      if (x >= BOARD_ITEM || y < 0 || x - d < 0 || y + d >= BOARD_ITEM) break
      if (chessboard[x - d][y + d] === p) cnt += 1
    }
    if (cnt === 5)
      return true
    x--;
    y++;
  }

  return false
}
const initBoard = () => {
  chessboard = []
  for (let i = 0; i < BOARD_ITEM; i++) {
    let t = []
    for (let j = 0; j < BOARD_ITEM; j++) {
      t.push(0)
    }
    chessboard.push(t)
  }

}
const drawCanvas = () => {
  const canvas = canvasRef.value
  canvas.width = 680
  canvas.height = 680
  canvas.onmousedown = draw
  const ctx = canvas.getContext("2d");
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  ctx.beginPath()
  ctx.lineWidth = 2
  ctx.fillStyle = '#d2d97a'
  ctx.fillRect(0, 0, 680, 680)
  for (let x = 0; x < BOARD_ITEM; x++) {
    ctx.moveTo(START + x * OFFSET, START)
    ctx.lineTo(START + x * OFFSET, START + OFFSET * (BOARD_ITEM - 1))
  }
  for (let y = 0; y < BOARD_ITEM; y++) {
    ctx.moveTo(START, START + y * OFFSET)
    ctx.lineTo(START + OFFSET * (BOARD_ITEM - 1), START + OFFSET * y)
  }
  ctx.moveTo(START - 1, START)
  ctx.lineTo(START + (BOARD_ITEM - 1) * OFFSET + 1, START)
  ctx.moveTo(START - 1, START + (BOARD_ITEM - 1) * OFFSET)
  ctx.lineTo(START + (BOARD_ITEM - 1) * OFFSET + 1, START + (BOARD_ITEM - 1) * OFFSET)
  ctx.strokeStyle = 'black'
  ctx.stroke()
  for (let x = 0; x < BOARD_ITEM; x++) {
    for (let y = 0; y < BOARD_ITEM; y++) {
      if (chessboard[x][y] === 1) {
        ctx.beginPath()
        ctx.fillStyle = "black"
        ctx.arc(x * OFFSET + START, y * OFFSET + START, 20, 0, Math.PI * 2)
        ctx.fill()
      }
      if (chessboard[x][y] === 2) {
        ctx.beginPath()
        ctx.fillStyle = "white"
        ctx.arc(x * OFFSET + START, y * OFFSET + START, 20, 0, Math.PI * 2)
        ctx.fill()
      }
    }
  }
}
const joinRoom = (row) => {
  console.log(row)
  if (row.number === 2) {
    message.error("此房间已满！不可加入！")
    return
  }
  ws.send(JSON.stringify({type: "joinRoom", data: row.roomName}))

}
const leaveRoom = () => {
  ws.send(JSON.stringify({type: "leaveRoom", data: roomInfo.value.roomName}))
  isGame.value = false
  isReady.value = false
  readyStatus.value.enemy = false
  readyStatus.value.player = false
  message.success("离开房间成功！")

}
const userStore = useUserStore()
const initWebSocket = () => {
  ws = new WebSocket("ws://localhost:8080/ws/" + userStore.user.username)

  ws.onopen = function () {
    message.success("连接服务器成功！")
  }

  ws.onmessage = (evt) => {
    console.log(evt.data)
    var result = JSON.parse(evt.data)
    if (result.type === "createRoomError") {
      message.error(result.data)
    }
    if (result.type === "createRoomSuccess") {
      message.success("房间创建成功，房间号：" + result.data);
      roomInfo.value.roomName = result.data
      isGame.value = true
    }
    if (result.type === "roomList") {
      message.success("房间刷新成功！");
      roomList.value = result.data
      console.log("roomList",roomList.value);
    }
    if (result.type === "joinSuccess") {
      message.success("加入房间成功！");
      isGame.value = true
      roomInfo.value.roomName = result.data
    }
    if (result.type === "roomInfo") {
      getEnemyInfo(result.data)
    }
    if (result.type === "leaveRoom") {
      roomInfo.value.enemy = {}
      readyStatus.value.enemy = false
      roomInfo.value.messageInfo = []
      message.warning("对方离开了房间！")
    }
    if (result.type === "joinError") {
      message.error(result.data)
    }
    if (result.type === "readySuccess") {
      readySuccess(result.data)
    }
    if (result.type === "unReadySuccess") {
      unReadySuccess(result.data)
    }
    if (result.type === "startBattle") {
      startBattle(result.data)
    }
    if (result.type === "play") {
      enemyPlay(result.data)
    }
    if (result.type === "win") {
      win(result.data)
    }
    if (result.type === "message"){
      receiveMessage(result.data)
    }
  }

  ws.onclose = () => {
    message.error("断开连接了Bro！")
  }

}

const refreshRoom = async () => {
  ws.send(JSON.stringify({type: "roomList", data: null}))
}
const createRoom = async () => {
  ws.send(JSON.stringify({type: "createRoom", data: roomName.value}))
  showModal.value = false
}
const isGame = ref(false)
const showModal = ref(false)
const roomName = ref("")
const isReady = ref(false)

const getEnemyInfo = async (data) => {
  var searchName = ""
  if (data.blackName === userStore.user.username) {
    searchName = data.whiteName
    if (data.whiteStatus === "已准备") {
      readyStatus.value.enemy = true
    }
  } else {
    searchName = data.blackName
    if (data.blackStatus === "已准备") {
      readyStatus.value.enemy = true
    }
  }
  const result = await userGetEnemyAPI(searchName)
  roomInfo.value.enemy = result.data
}
const ready = () => {
  ws.send(JSON.stringify({type: "ready", data: roomInfo.value.roomName}))
}

const unReady = () => {
  ws.send(JSON.stringify({type: "unReady", data: roomInfo.value.roomName}))
}

const readySuccess = (username) => {
  if (username === userStore.user.username) {
    readyStatus.value.player = true
    isReady.value = true
  } else {
    readyStatus.value.enemy = true
  }

}

const unReadySuccess = (username) => {
  if (username === userStore.user.username) {
    readyStatus.value.player = false
    isReady.value = false
  } else {
    readyStatus.value.enemy = false
  }
}

const startBattle = (blackName) => {
  initBoard()
  drawCanvas()
  if (userStore.user.username === blackName) {
    message.success("现在是你的回合！");
    player.value.color = 1
    player.value.isPlay = true
  } else {
    player.value.color = 2
  }
}

const enemyPlay = (data) => {
  player.value.isPlay = true
  chessboard[data.x][data.y] = data.color
  drawCanvas()
  message.warning("现在是你的回合！")
}

const win = (winName) => {
  if (winName === userStore.user.username) {
    message.success("您赢了！！！")
  } else {
    message.error("您输了！！！")
  }
  player.value.isPlay = false
}

const messageInfo = ref("")
const sendMessage = ()=>{
  if (messageInfo.value === ""){
    message.warning("哥们啥也没输入，你发集贸呢？")
    return
  }

  ws.send(JSON.stringify({
    type: "message",
    data: {
      roomName: roomInfo.value.roomName,
      message: messageInfo.value
    }
  }))
  messageInfo.value = ""
}

const receiveMessage = (data)=>{
  roomInfo.value.messageInfo.push(data)
}
onMounted(() => {
  console.log("游戏页面")
  // initBoard()
  // drawCanvas()
  initWebSocket()
  emitter.on("initChessBoard", () => {
    initBoard()
    drawCanvas()
  })

})
</script>

<template>

  <div v-show="isGame === false">
    <n-modal-provider>
      <n-modal v-model:show="showModal" :mask-closable="false">
        <n-card
            style="width: 400px"
            title="创建房间"
            :bordered="false"
            size="huge"
            role="dialog"
            aria-modal="true"
        >
          <div style="margin-left: 2px; margin-bottom: 3px">
            房间名
          </div>
          <n-input v-model:value="roomName" type="text" placeholder="输入房间名"/>
          <template #footer>
            <div style="display: flex; justify-content: end;">
              <n-button style="margin-right: 5px;" @click="showModal=false; roomName=''">取消</n-button>
              <n-button @click="createRoom">创建房间</n-button>
            </div>

          </template>
        </n-card>
      </n-modal>
    </n-modal-provider>

    <div style="display: flex; justify-content: end;">
      <n-button type="info" @click="refreshRoom" style="margin-right: 50px;">刷新房间</n-button>
      <n-button type="error" @click="showModal=true" style="margin-right: 50px;">创建房间</n-button>

    </div>
<!--    <el-table :data="roomList" style="width: 100%; background: #79bbff">-->
<!--      <el-table-column prop="roomName" label="房间名" width="280"/>-->
<!--      <el-table-column prop="number" label="玩家人数" width="280"/>-->
<!--      <el-table-column label="操作">-->
<!--        <template #default="scope">-->
<!--          <n-button-->
<!--              type="info"-->
<!--              @click="joinRoom(scope.row)"-->
<!--          >-->
<!--            加入房间-->

<!--          </n-button>-->
<!--        </template>-->

<!--      </el-table-column>-->
<!--    </el-table>-->
    <el-card style="margin: 10px; padding:20px; padding-bottom: 80px; height: 650px">
      <el-scrollbar height="650px">
      <div style="display: flex; flex-direction: row; flex-wrap: wrap; justify-content: left">

          <el-card shadow="hover" style="width: 200px; height: 200px; margin: 15px" v-for="i in roomList" :key="i">
            <h2>Sky的房间</h2>
            <h3>房间人数：2</h3>
            <h4>玩家1：Sky</h4>
            <h4>玩家2：小虎</h4>
            <div style="height: 20px"></div>
            <n-button type="info" style="margin-left: 60px">
              加入房间
            </n-button>
          </el-card>

      </div>
      </el-scrollbar>
    </el-card>
  </div>
  <div v-show="isGame === true">
    <div style="display: flex">

      <div style="margin-right: 10px;">
        <n-card :title="roomInfo.roomName" style="width: 330px;">
          <n-card title="您的信息" hoverable style="margin-bottom: 10px; height: 150px">
            <div style="display: flex">
              <n-avatar
                  :size="48"
                  :src="userStore.user.avatar"
              />
              <div style="margin-left: 10px">
                用户名：{{ userStore.user.username }} <br/>
                <n-icon v-if="readyStatus.player" size="40" style="margin-left: 10px;" color="#26de81">
                  <ReadyIcon/>
                </n-icon>
              </div>
            </div>
          </n-card>
          <n-card title="对手的信息" hoverable style="margin-bottom: 10px; height: 150px">
            <div style="display: flex">
              <n-avatar
                  :size="48"
                  :src="roomInfo.enemy.avatar"
              />
              <div style="margin-left: 10px">
                用户名：{{ roomInfo.enemy.username }} <br/>
                <n-icon v-if="readyStatus.enemy" size="40" style="margin-left: 10px;" color="#26de81">
                  <ReadyIcon/>
                </n-icon>
              </div>
            </div>
          </n-card>
        </n-card>
        <div>
          <n-button style="margin-top: 10px;" strong secondary type="info" @click="ready" v-if="isReady == false">
            准备游戏
          </n-button>
          <n-button style="margin-top: 10px;" strong secondary type="info" @click="unReady" v-if="isReady == true">
            取消准备
          </n-button>
          <n-button style="margin-left: 20px; margin-top: 10px;" strong secondary type="error" @click="leaveRoom">
            退出房间
          </n-button>
        </div>
      </div>
      <canvas
          ref="canvasRef"
          style="width: 680px; height: 680px; "
      >
      </canvas>

      <div style="width: 300px; height: 600px; background: rgb(245, 245, 245)">
        <div style="width: 300px; height: 550px; ">
          <el-scrollbar height="550px">
            <div style="width: 300px; margin-bottom: 10px; ">
              <div v-for="(item, index) in roomInfo.messageInfo" :key="index">
                <div v-if="item.username !== userStore.user.username" style="display: flex; justify-content: left">
                  <n-avatar
                      round
                      size="small"
                      :src="roomInfo.enemy.avatar"
                      style="margin-left: 10px; margin-top: 10px; margin-right: 3px"
                  />
                  <div style="background: rgb(255, 255, 255); max-width: 240px; margin-top: 6px; border-radius: 5px;word-break: break-all; word-wrap: break-word; white-space: pre-wrap; padding: 5px">
                    {{item.message}}
                  </div>
                </div>
                <div v-if="item.username === userStore.user.username" style="display: flex; justify-content: right">
                  <div style="background: rgb(149, 236, 105); max-width: 240px; margin-top: 6px; border-radius: 5px;word-break: break-all; word-wrap: break-word; white-space: pre-wrap; padding: 5px">
                    {{item.message}}
                  </div>
                  <n-avatar
                      round
                      size="small"
                      :src="userStore.user.avatar"
                      style="margin-right: 5px; margin-top: 10px; margin-left: 3px"
                  />
                </div>
              </div>

            </div>
          </el-scrollbar>
        </div>
        <n-input
            placeholder="要发送的信息"
            type="textarea"
            size="small"
            v-model:value="messageInfo"
            :autosize="{
              minRows: 3,
              maxRows: 3
            }"
        />
        <div style="width: 300px;display: flex; justify-content: right">
          <n-button type="primary" dashed @click="sendMessage">发送</n-button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>

</style>